home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / kuaqe2.zip / WEAPONS.QC < prev    next >
Text File  |  1996-10-06  |  41KB  |  1,836 lines

  1. /*
  2.  
  3. Modified Weapons.QC for cool stuff by Eli
  4.  
  5. */
  6.  
  7. float FLASHLIGHT_ON = 1;
  8. float LASER_ON = 2;
  9. float CHASECAM_ON = 4;
  10. float FOOTSTEPS_ON = 8;
  11. float SVC_SETVIEWPORT    = 5;
  12. float SVC_SETVIEWANGLES    = 10;
  13.  
  14. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  15. void () player_run;
  16. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  17. void(vector org, vector vel, float damage) SpawnBlood;
  18. void() SuperDamageSound;
  19. void (entity FlashlightOwner) FlashlightToggle;
  20. void () FlashlightTrack;
  21. void (entity LaserOwner) LaserToggle;
  22. void () LaserTrack;
  23. void () ChasecamToggle;
  24. void () ChasecamTrack;
  25. void (float opt) ChasecamRemove;
  26. void () ChasecamRestart;
  27. void (entity ChasecamOwner) ChasecamStart;
  28. void () EntityRemover;
  29. void () FlareTouch;
  30. void () FlareFire;
  31. void () FootstepsToggle;
  32. void (vector src, vector dir, float punch, vector spread) ShellEject;
  33. void () ChangeSkin;
  34. void () W_FireFlame;
  35. void () BurnSelf;
  36.  
  37. // called by worldspawn
  38. void() W_Precache =
  39. {
  40.     precache_model ("progs/laser.mdl"); // Enforcer laser for flare
  41.         precache_model ("progs/null.spr");  // Null sprite for invisibility
  42.     precache_sound ("misc/power.wav");  // new rocket explosion
  43.         precache_sound ("player/step.wav"); // Footsteps
  44.         precache_sound ("hknight/hit.wav"); // flamethrower
  45.  
  46.     precache_sound ("weapons/r_exp3.wav");  // new rocket explosion
  47.     precache_sound ("weapons/rocket1i.wav");        // spike gun
  48.     precache_sound ("weapons/sgun1.wav");
  49.     precache_sound ("weapons/guncock.wav"); // player shotgun
  50.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  51.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  52.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  53.     precache_sound ("weapons/spike2.wav");  // super spikes
  54.     precache_sound ("weapons/tink1.wav");   // spikes tink (used in c code)
  55.     precache_sound ("weapons/grenade.wav"); // grenade launcher
  56.     precache_sound ("weapons/bounce.wav");          // grenade bounce
  57.     precache_sound ("weapons/shotgn2.wav"); // super shotgun
  58.         precache_sound2 ("blob/land1.wav");
  59.         precache_sound ("plats/medplat1.wav");
  60.         precache_sound ("doors/ddoor1.wav");
  61.         precache_sound ("items/protect3.wav");
  62.         precache_sound ("items/damage3.wav");
  63. };
  64.  
  65. float() crandom =
  66. {
  67.     return 2*(random() - 0.5);
  68. };
  69.  
  70. /*
  71. ================
  72. W_FireAxe
  73. ================
  74. */
  75. void() W_FireAxe =
  76. {
  77.     local   vector  source;
  78.     local   vector  org;
  79.  
  80.     source = self.origin + '0 0 16';
  81.     traceline (source, source + v_forward*64, FALSE, self);
  82.     if (trace_fraction == 1.0)
  83.         return;
  84.     
  85.     org = trace_endpos - v_forward*4;
  86.  
  87.     if (trace_ent.takedamage)
  88.     {
  89.         trace_ent.axhitme = 1;
  90.         SpawnBlood (org, '0 0 0', 20);
  91.         T_Damage (trace_ent, self, self, 20);
  92.     }
  93.     else
  94.     {       // hit wall
  95.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  96.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  97.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  98.         WriteCoord (MSG_BROADCAST, org_x);
  99.         WriteCoord (MSG_BROADCAST, org_y);
  100.         WriteCoord (MSG_BROADCAST, org_z);
  101.     }
  102. };
  103.  
  104.  
  105. //============================================================================
  106.  
  107.  
  108. vector() wall_velocity =
  109. {
  110.     local vector    vel;
  111.     
  112.     vel = normalize (self.velocity);
  113.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  114.     vel = vel + 2*trace_plane_normal;
  115.     vel = vel * 200;
  116.     
  117.     return vel;
  118. };
  119.  
  120.  
  121. /*
  122. ================
  123. SpawnMeatSpray
  124. ================
  125. */
  126. void(vector org, vector vel) SpawnMeatSpray =
  127. {
  128.     local   entity missile, mpuff;
  129.     local   vector  org;
  130.  
  131.     missile = spawn ();
  132.     missile.owner = self;
  133.     missile.movetype = MOVETYPE_BOUNCE;
  134.     missile.solid = SOLID_NOT;
  135.  
  136.     makevectors (self.angles);
  137.  
  138.     missile.velocity = vel;
  139.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  140.  
  141.     missile.avelocity = '3000 1000 2000';
  142.     
  143. // set missile duration
  144.     missile.nextthink = time + 1;
  145.     missile.think = SUB_Remove;
  146.  
  147.     setmodel (missile, "progs/zom_gib.mdl");
  148.     setsize (missile, '0 0 0', '0 0 0');            
  149.     setorigin (missile, org);
  150. };
  151.  
  152. /*
  153. ================
  154. SpawnBlood
  155. ================
  156. */
  157. void(vector org, vector vel, float damage) SpawnBlood =
  158. {
  159.     particle (org, vel*0.1, 73, damage*2);
  160. };
  161.  
  162. /*
  163. ================
  164. spawn_touchblood
  165. ================
  166. */
  167. void(float damage) spawn_touchblood =
  168. {
  169.     local vector    vel;
  170.  
  171.     vel = wall_velocity () * 0.2;
  172.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  173. };
  174.  
  175.  
  176. /*
  177. ================
  178. SpawnChunk
  179. ================
  180. */
  181. void(vector org, vector vel) SpawnChunk =
  182. {
  183.     particle (org, vel*0.02, 0, 10);
  184. };
  185.  
  186. /*
  187. ==============================================================================
  188.  
  189. MULTI-DAMAGE
  190.  
  191. Collects multiple small damages into a single damage
  192.  
  193. ==============================================================================
  194. */
  195.  
  196. entity  multi_ent;
  197. float   multi_damage;
  198.  
  199. void() ClearMultiDamage =
  200. {
  201.     multi_ent = world;
  202.     multi_damage = 0;
  203. };
  204.  
  205. void() ApplyMultiDamage =
  206. {
  207.     if (!multi_ent)
  208.         return;
  209.     T_Damage (multi_ent, self, self, multi_damage);
  210. };
  211.  
  212. void(entity hit, float damage) AddMultiDamage =
  213. {
  214.     if (!hit)
  215.         return;
  216.     
  217.     if (hit != multi_ent)
  218.     {
  219.         ApplyMultiDamage ();
  220.         multi_damage = damage;
  221.         multi_ent = hit;
  222.     }
  223.     else
  224.         multi_damage = multi_damage + damage;
  225. };
  226.  
  227. /*
  228. ==============================================================================
  229.  
  230. BULLETS
  231.  
  232. ==============================================================================
  233. */
  234.  
  235. /*
  236. ================
  237. TraceAttack
  238. ================
  239. */
  240. void(float damage, vector dir) TraceAttack =
  241. {
  242.     local   vector  vel, org;
  243.     
  244.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  245.     vel = vel + 2*trace_plane_normal;
  246.     vel = vel * 200;
  247.  
  248.     org = trace_endpos - dir*4;
  249.  
  250.     if (trace_ent.takedamage)
  251.     {
  252.         SpawnBlood (org, vel*0.2, damage);
  253.         AddMultiDamage (trace_ent, damage);
  254.     }
  255.     else
  256.     {
  257.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  258.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  259.         WriteCoord (MSG_BROADCAST, org_x);
  260.         WriteCoord (MSG_BROADCAST, org_y);
  261.         WriteCoord (MSG_BROADCAST, org_z);
  262.     }
  263. };
  264.  
  265. /*
  266. ================
  267. FireBullets
  268.  
  269. Used by shotgun, super shotgun, and enemy soldier firing
  270. Go to the trouble of combining multiple pellets into a single damage call.
  271. ================
  272. */
  273. void(float shotcount, vector dir, vector spread) FireBullets =
  274. {
  275.     local   vector direction;
  276.     local   vector  src;
  277.     
  278.     makevectors(self.v_angle);
  279.  
  280.     src = self.origin + v_forward*10;
  281.     src_z = self.absmin_z + self.size_z * 0.7;
  282.  
  283.     ClearMultiDamage ();
  284.     while (shotcount > 0)
  285.     {
  286.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  287.  
  288.         traceline (src, src + direction*2048, FALSE, self);
  289.         if (trace_fraction != 1.0)
  290.             TraceAttack (4, direction);
  291.  
  292.         shotcount = shotcount - 1;
  293.     }
  294.     ApplyMultiDamage ();
  295. };
  296.  
  297. /*
  298. ================
  299. W_FireShotgun
  300. ================
  301. */
  302. void() W_FireShotgun =
  303. {
  304.     local vector dir;
  305.  
  306.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); 
  307.  
  308.     self.punchangle_x = -2;
  309.     
  310.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  311.     dir = aim (self, 100000);
  312.     FireBullets (6, dir, '0.04 0.04 0');
  313.  
  314.         // added for shell eject
  315.         ShellEject (self.origin + '0 0 16' + v_forward*3,dir, 200, '.5 .5 .5');
  316. };
  317.  
  318.  
  319. /*
  320. ================
  321. W_FireSuperShotgun
  322. ================
  323. */
  324. void() W_FireSuperShotgun =
  325. {
  326.     local vector dir;
  327.  
  328.     if (self.currentammo == 1)
  329.     {
  330.         W_FireShotgun ();
  331.         return;
  332.     }
  333.         
  334.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); 
  335.  
  336.     self.punchangle_x = -4;
  337.     
  338.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  339.     dir = aim (self, 100000);
  340.     FireBullets (14, dir, '0.14 0.08 0');
  341.  
  342.         ShellEject (self.origin + '0 0 16' + v_forward*3,dir, 400, '0.3 0.3 0.3');
  343.         ShellEject (self.origin + '0 0 16' + v_forward*3,dir, 400, '0.3 0.3 0.3');
  344.  
  345. };
  346.  
  347.  
  348. /*
  349. ==============================================================================
  350.  
  351. ROCKETS
  352.  
  353. ==============================================================================
  354. */
  355.  
  356. void()  s_explode1      =       [0,             s_explode2] {};
  357. void()  s_explode2      =       [1,             s_explode3] {};
  358. void()  s_explode3      =       [2,             s_explode4] {};
  359. void()  s_explode4      =       [3,             s_explode5] {};
  360. void()  s_explode5      =       [4,             s_explode6] {};
  361. void()  s_explode6      =       [5,             SUB_Remove] {};
  362.  
  363. void() BecomeExplosion =
  364. {
  365.     self.movetype = MOVETYPE_NONE;
  366.     self.velocity = '0 0 0';
  367.     self.touch = SUB_Null;
  368.     setmodel (self, "progs/s_explod.spr");
  369.     self.solid = SOLID_NOT;
  370.     s_explode1 ();
  371. };
  372.  
  373. void() T_MissileTouch =
  374. {
  375.     local float     damg;
  376.  
  377.     if (other == self.owner)
  378.         return;         // don't explode on owner
  379.  
  380.     if (pointcontents(self.origin) == CONTENT_SKY)
  381.     {
  382.         remove(self);
  383.         return;
  384.     }
  385.  
  386.     damg = 100 + random()*20;
  387.     
  388.     if (other.health)
  389.     {
  390.         if (other.classname == "monster_shambler")
  391.             damg = damg * 0.5;      // mostly immune
  392.         T_Damage (other, self, self.owner, damg );
  393.     }
  394.  
  395.     // don't do radius damage to the other, because all the damage
  396.     // was done in the impact
  397.     T_RadiusDamage (self, self.owner, 120, other);
  398.  
  399. //      sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  400.     self.origin = self.origin - 8*normalize(self.velocity);
  401.  
  402.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  403.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  404.     WriteCoord (MSG_BROADCAST, self.origin_x);
  405.     WriteCoord (MSG_BROADCAST, self.origin_y);
  406.     WriteCoord (MSG_BROADCAST, self.origin_z);
  407.  
  408.     BecomeExplosion ();
  409. };
  410.  
  411.  
  412.  
  413. /*
  414. ================
  415. W_FireRocket
  416. ================
  417. */
  418. void() W_FireRocket =
  419. {
  420.     local   entity missile, mpuff;
  421.     
  422.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  423.     
  424.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  425.  
  426.     self.punchangle_x = -2;
  427.  
  428.     missile = spawn ();
  429.     missile.owner = self;
  430.     missile.movetype = MOVETYPE_FLYMISSILE;
  431.     missile.solid = SOLID_BBOX;
  432.         
  433. // set missile speed    
  434.  
  435.     makevectors (self.v_angle);
  436.     missile.velocity = aim(self, 1000);
  437.     missile.velocity = missile.velocity * 1000;
  438.     missile.angles = vectoangles(missile.velocity);
  439.     
  440.     missile.touch = T_MissileTouch;
  441.     
  442. // set missile duration
  443.     missile.nextthink = time + 5;
  444.     missile.think = SUB_Remove;
  445.  
  446.     setmodel (missile, "progs/missile.mdl");
  447.     setsize (missile, '0 0 0', '0 0 0');            
  448.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  449. };
  450.  
  451. /*
  452. ===============================================================================
  453.  
  454. LIGHTNING
  455.  
  456. ===============================================================================
  457. */
  458.  
  459. /*
  460. =================
  461. LightningDamage
  462. =================
  463. */
  464. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  465. {
  466.     local entity            e1, e2;
  467.     local vector            f;
  468.     
  469.     f = p2 - p1;
  470.     normalize (f);
  471.     f_x = 0 - f_y;
  472.     f_y = f_x;
  473.     f_z = 0;
  474.     f = f*16;
  475.  
  476.     e1 = e2 = world;
  477.  
  478.     traceline (p1, p2, FALSE, self);
  479.     if (trace_ent.takedamage)
  480.     {
  481.         particle (trace_endpos, '0 0 100', 225, damage*4);
  482.         T_Damage (trace_ent, from, from, damage);
  483.         if (self.classname == "player")
  484.         {
  485.             if (other.classname == "player")
  486.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  487.         }
  488.     }
  489.     e1 = trace_ent;
  490.  
  491.     traceline (p1 + f, p2 + f, FALSE, self);
  492.     if (trace_ent != e1 && trace_ent.takedamage)
  493.     {
  494.         particle (trace_endpos, '0 0 100', 225, damage*4);
  495.         T_Damage (trace_ent, from, from, damage);
  496.     }
  497.     e2 = trace_ent;
  498.  
  499.     traceline (p1 - f, p2 - f, FALSE, self);
  500.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  501.     {
  502.         particle (trace_endpos, '0 0 100', 225, damage*4);
  503.         T_Damage (trace_ent, from, from, damage);
  504.     }
  505. };
  506.  
  507.  
  508. void() W_FireLightning =
  509. {
  510.     local   vector          org;
  511.  
  512.     if (self.ammo_cells < 1)
  513.     {
  514.         self.weapon = W_BestWeapon ();
  515.         W_SetCurrentAmmo ();
  516.         return;
  517.     }
  518.  
  519. // explode if under water
  520.     if (self.waterlevel > 1)
  521.     {
  522.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  523.         self.ammo_cells = 0;
  524.         W_SetCurrentAmmo ();
  525.         return;
  526.     }
  527.  
  528.     if (self.t_width < time)
  529.     {
  530.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  531.         self.t_width = time + 0.6;
  532.     }
  533.     self.punchangle_x = -2;
  534.  
  535.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  536.  
  537.     org = self.origin + '0 0 16';
  538.     
  539.     traceline (org, org + v_forward*600, TRUE, self);
  540.  
  541.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  542.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  543.     WriteEntity (MSG_BROADCAST, self);
  544.     WriteCoord (MSG_BROADCAST, org_x);
  545.     WriteCoord (MSG_BROADCAST, org_y);
  546.     WriteCoord (MSG_BROADCAST, org_z);
  547.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  548.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  549.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  550.  
  551.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  552. };
  553.  
  554.  
  555. //=============================================================================
  556.  
  557.  
  558. void() GrenadeExplode =
  559. {
  560.     T_RadiusDamage (self, self.owner, 120, world);
  561.  
  562.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  563.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  564.     WriteCoord (MSG_BROADCAST, self.origin_x);
  565.     WriteCoord (MSG_BROADCAST, self.origin_y);
  566.     WriteCoord (MSG_BROADCAST, self.origin_z);
  567.  
  568.     BecomeExplosion ();
  569. };
  570.  
  571. void() GrenadeTouch =
  572. {
  573.     if (other == self.owner)
  574.         return;         // don't explode on owner
  575.     if (other.takedamage == DAMAGE_AIM)
  576.     {
  577.         GrenadeExplode();
  578.         return;
  579.     }
  580.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  581.     if (self.velocity == '0 0 0')
  582.         self.avelocity = '0 0 0';
  583. };
  584.  
  585. /*
  586. ================
  587. W_FireGrenade
  588. ================
  589. */
  590. void() W_FireGrenade =
  591. {
  592.     local   entity missile, mpuff;
  593.     
  594.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  595.     
  596.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  597.  
  598.     self.punchangle_x = -2;
  599.  
  600.     missile = spawn ();
  601.     missile.owner = self;
  602.     missile.movetype = MOVETYPE_BOUNCE;
  603.     missile.solid = SOLID_BBOX;
  604.     missile.classname = "grenade";
  605.         
  606. // set missile speed    
  607.  
  608.     makevectors (self.v_angle);
  609.  
  610.     if (self.v_angle_x)
  611.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  612.     else
  613.     {
  614.         missile.velocity = aim(self, 10000);
  615.         missile.velocity = missile.velocity * 600;
  616.         missile.velocity_z = 200;
  617.     }
  618.  
  619.     missile.avelocity = '300 300 300';
  620.  
  621.     missile.angles = vectoangles(missile.velocity);
  622.     
  623.     missile.touch = GrenadeTouch;
  624.     
  625. // set missile duration
  626.     missile.nextthink = time + 2.5;
  627.     missile.think = GrenadeExplode;
  628.  
  629.     setmodel (missile, "progs/grenade.mdl");
  630.     setsize (missile, '0 0 0', '0 0 0');            
  631.     setorigin (missile, self.origin);
  632. };
  633.  
  634.  
  635. //=============================================================================
  636.  
  637. void() spike_touch;
  638. void() superspike_touch;
  639.  
  640. /*
  641. ===============
  642. launch_spike
  643.  
  644. Used for both the player and the ogre
  645. ===============
  646. */
  647. void(vector org, vector dir) launch_spike =
  648. {
  649.     newmis = spawn ();
  650.     newmis.owner = self;
  651.     newmis.movetype = MOVETYPE_FLYMISSILE;
  652.     newmis.solid = SOLID_BBOX;
  653.  
  654.     newmis.angles = vectoangles(dir);
  655.     
  656.     newmis.touch = spike_touch;
  657.     newmis.classname = "spike";
  658.     newmis.think = SUB_Remove;
  659.     newmis.nextthink = time + 6;
  660.     setmodel (newmis, "progs/spike.mdl");
  661.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  662.     setorigin (newmis, org);
  663.  
  664.     newmis.velocity = dir * 1000;
  665. };
  666.  
  667. void() W_FireSuperSpikes =
  668. {
  669.     local vector    dir;
  670.     local entity    old;
  671.     
  672.     sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  673.     self.attack_finished = time + 0.2;
  674.     self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  675.     dir = aim (self, 1000);
  676.     launch_spike (self.origin + '0 0 16', dir);
  677.     newmis.touch = superspike_touch;
  678.     setmodel (newmis, "progs/s_spike.mdl");
  679.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  680.     self.punchangle_x = -2;
  681. };
  682.  
  683. void(float ox) W_FireSpikes =
  684. {
  685.     local vector    dir;
  686.     local entity    old;
  687.     
  688.     makevectors (self.v_angle);
  689.     
  690.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  691.     {
  692.         W_FireSuperSpikes ();
  693.         return;
  694.     }
  695.  
  696.     if (self.ammo_nails < 1)
  697.     {
  698.         self.weapon = W_BestWeapon ();
  699.         W_SetCurrentAmmo ();
  700.         return;
  701.     }
  702.  
  703.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  704.     self.attack_finished = time + 0.2;
  705.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  706.     dir = aim (self, 1000);
  707.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  708.  
  709.     self.punchangle_x = -2;
  710. };
  711.  
  712.  
  713.  
  714. .float hit_z;
  715. void() spike_touch =
  716. {
  717. local float rand;
  718.     if (other == self.owner)
  719.         return;
  720.  
  721.     if (other.solid == SOLID_TRIGGER)
  722.         return; // trigger field, do nothing
  723.  
  724.     if (pointcontents(self.origin) == CONTENT_SKY)
  725.     {
  726.         remove(self);
  727.         return;
  728.     }
  729.     
  730. // hit something that bleeds
  731.     if (other.takedamage)
  732.     {
  733.         spawn_touchblood (9);
  734.         T_Damage (other, self, self.owner, 9);
  735.     }
  736.     else
  737.     {
  738.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  739.         
  740.         if (self.classname == "wizspike")
  741.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  742.         else if (self.classname == "knightspike")
  743.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  744.         else
  745.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  746.         WriteCoord (MSG_BROADCAST, self.origin_x);
  747.         WriteCoord (MSG_BROADCAST, self.origin_y);
  748.         WriteCoord (MSG_BROADCAST, self.origin_z);
  749.     }
  750.  
  751.     remove(self);
  752.  
  753. };
  754.  
  755. void() superspike_touch =
  756. {
  757. local float rand;
  758.     if (other == self.owner)
  759.         return;
  760.  
  761.     if (other.solid == SOLID_TRIGGER)
  762.         return; // trigger field, do nothing
  763.  
  764.     if (pointcontents(self.origin) == CONTENT_SKY)
  765.     {
  766.         remove(self);
  767.         return;
  768.     }
  769.     
  770. // hit something that bleeds
  771.     if (other.takedamage)
  772.     {
  773.         spawn_touchblood (18);
  774.         T_Damage (other, self, self.owner, 18);
  775.     }
  776.     else
  777.     {
  778.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  779.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  780.         WriteCoord (MSG_BROADCAST, self.origin_x);
  781.         WriteCoord (MSG_BROADCAST, self.origin_y);
  782.         WriteCoord (MSG_BROADCAST, self.origin_z);
  783.     }
  784.  
  785.     remove(self);
  786.  
  787. };
  788.  
  789. /*
  790. ===============================================================================
  791.  
  792. PLAYER WEAPON USE
  793.  
  794. ===============================================================================
  795. */
  796.  
  797. void() W_SetCurrentAmmo =
  798. {
  799.     player_run ();          // get out of any weapon firing states
  800.  
  801.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  802.     
  803.     if (self.weapon == IT_AXE)
  804.     {
  805.         self.currentammo = 0;
  806.         self.weaponmodel = "progs/v_axe.mdl";
  807.         self.weaponframe = 0;
  808.     }
  809.         else if (self.weapon == IT_MORNINGSTAR)
  810.         {
  811.                 self.currentammo = 0;
  812.                 self.weaponmodel = "progs/v_star.mdl";
  813.                 self.weaponframe = 0;
  814.         }
  815.     else if (self.weapon == IT_SHOTGUN)
  816.     {
  817.         self.currentammo = self.ammo_shells;
  818.         self.weaponmodel = "progs/v_shot.mdl";
  819.         self.weaponframe = 0;
  820.         self.items = self.items | IT_SHELLS;
  821.     }
  822.     else if (self.weapon == IT_SUPER_SHOTGUN)
  823.     {
  824.         self.currentammo = self.ammo_shells;
  825.         self.weaponmodel = "progs/v_shot2.mdl";
  826.         self.weaponframe = 0;
  827.         self.items = self.items | IT_SHELLS;
  828.     }
  829.     else if (self.weapon == IT_NAILGUN)
  830.     {
  831.         self.currentammo = self.ammo_nails;
  832.         self.weaponmodel = "progs/v_nail.mdl";
  833.         self.weaponframe = 0;
  834.         self.items = self.items | IT_NAILS;
  835.     }
  836.     else if (self.weapon == IT_SUPER_NAILGUN)
  837.     {
  838.         self.currentammo = self.ammo_nails;
  839.         self.weaponmodel = "progs/v_nail2.mdl";
  840.         self.weaponframe = 0;
  841.         self.items = self.items | IT_NAILS;
  842.     }
  843.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  844.     {
  845.         self.currentammo = self.ammo_rockets;
  846.         self.weaponmodel = "progs/v_rock.mdl";
  847.         self.weaponframe = 0;
  848.         self.items = self.items | IT_ROCKETS;
  849.     }
  850.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  851.     {
  852.         self.currentammo = self.ammo_rockets;
  853.         self.weaponmodel = "progs/v_rock2.mdl";
  854.         self.weaponframe = 0;
  855.         self.items = self.items | IT_ROCKETS;
  856.     }
  857.         else if (self.weapon == IT_FLAMETHROWER)
  858.         {
  859.                 self.currentammo = self.ammo_shells;
  860.                 self.weaponmodel = "progs/v_rock.mdl";
  861.                 self.weaponframe = 0;
  862.                 self.items = self.items | IT_SHELLS;
  863.         }
  864.     else if (self.weapon == IT_LIGHTNING)
  865.     {
  866.         self.currentammo = self.ammo_cells;
  867.         self.weaponmodel = "progs/v_light.mdl";
  868.         self.weaponframe = 0;
  869.         self.items = self.items | IT_CELLS;
  870.     }
  871.     else
  872.     {
  873.         self.currentammo = 0;
  874.         self.weaponmodel = "";
  875.         self.weaponframe = 0;
  876.     }
  877. };
  878.  
  879. float() W_BestWeapon =
  880. {
  881.     local   float   it;
  882.     
  883.     it = self.items;
  884.  
  885.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  886.         return IT_LIGHTNING;
  887.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  888.         return IT_SUPER_NAILGUN;
  889.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  890.         return IT_SUPER_SHOTGUN;
  891.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  892.         return IT_NAILGUN;
  893.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  894.         return IT_SHOTGUN;
  895.         
  896. /*
  897.     if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  898.         return IT_ROCKET_LAUNCHER;
  899.     else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  900.         return IT_GRENADE_LAUNCHER;
  901.  
  902. */
  903.  
  904.     return IT_AXE;
  905. };
  906.  
  907. float() W_CheckNoAmmo =
  908. {
  909.     if (self.currentammo > 0)
  910.         return TRUE;
  911.  
  912.         if ((self.weapon == IT_AXE) || (self.weapon == IT_MORNINGSTAR))
  913.         return TRUE;
  914.     
  915.     self.weapon = W_BestWeapon ();
  916.  
  917.     W_SetCurrentAmmo ();
  918.     
  919. // drop the weapon down
  920.     return FALSE;
  921. };
  922.  
  923. /*
  924. ============
  925. W_Attack
  926.  
  927. An attack impulse can be triggered now
  928. ============
  929. */
  930. void()  player_axe1;
  931. void()  player_axeb1;
  932. void()  player_axec1;
  933. void()  player_axed1;
  934. void()  player_shot1;
  935. void()  player_nail1;
  936. void()  player_light1;
  937. void()  player_rocket1;
  938. void()  player_chain1;
  939. void()  player_chain3;
  940.  
  941. void() W_Attack =
  942. {
  943.     local   float   r;
  944.  
  945.     if (!W_CheckNoAmmo ())
  946.         return;
  947.  
  948.     makevectors     (self.v_angle);                 // calculate forward angle for velocity
  949.     self.show_hostile = time + 1;   // wake monsters up
  950.  
  951.     if (self.weapon == IT_AXE)
  952.     {
  953.         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  954.         r = random();
  955.         if (r < 0.25)
  956.             player_axe1 ();
  957.         else if (r<0.5)
  958.             player_axeb1 ();
  959.         else if (r<0.75)
  960.             player_axec1 ();
  961.         else
  962.             player_axed1 ();
  963.         self.attack_finished = time + 0.5;
  964.     }
  965.         else if (self.weapon == IT_MORNINGSTAR)
  966.         {
  967.                 if (!self.hook_out)
  968.                   player_chain1();
  969.                 else
  970.                   player_chain3();
  971.                 self.attack_finished = time + 0.1;
  972.         }
  973.         else if (self.weapon == IT_SHOTGUN)
  974.     {
  975.         player_shot1 ();
  976.         W_FireShotgun ();
  977.         self.attack_finished = time + 0.5;
  978.     }
  979.     else if (self.weapon == IT_SUPER_SHOTGUN)
  980.     {
  981.         player_shot1 ();
  982.         W_FireSuperShotgun ();
  983.         self.attack_finished = time + 0.7;
  984.     }
  985.     else if (self.weapon == IT_NAILGUN)
  986.     {
  987.         player_nail1 ();
  988.     }
  989.     else if (self.weapon == IT_SUPER_NAILGUN)
  990.     {
  991.         player_nail1 ();
  992.     }
  993.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  994.     {
  995.         player_rocket1();
  996.         W_FireGrenade();
  997.         self.attack_finished = time + 0.6;
  998.     }
  999.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1000.     {
  1001.         player_rocket1();
  1002.         W_FireRocket();
  1003.         self.attack_finished = time + 0.8;
  1004.     }
  1005.         else if (self.weapon == IT_FLAMETHROWER)
  1006.         {
  1007.                 player_shot1();
  1008.                 W_FireFlame ();
  1009.                 if (self.waterlevel >2)
  1010.                         self.attack_finished = time + 1;
  1011.                 else
  1012.                         self.attack_finished = time + 0.1;
  1013.         }
  1014.         else if (self.weapon == IT_LIGHTNING)
  1015.     {
  1016.         player_light1();
  1017.         self.attack_finished = time + 0.1;
  1018.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1019.     }
  1020. };
  1021.  
  1022. /*
  1023. ============
  1024. W_ChangeWeapon
  1025.  
  1026. ============
  1027. */
  1028. void() W_ChangeWeapon =
  1029. {
  1030.     local   float   it, am, fl;
  1031.     
  1032.     it = self.items;
  1033.     am = 0;
  1034.     
  1035.         if (self.impulse == 1)
  1036.     {
  1037.                 if (self.weapon == IT_AXE)
  1038.                 {
  1039.                   fl = IT_MORNINGSTAR;
  1040.                   if ((!deathmatch) && (!coop))
  1041.                     sprint (self, "Cheater\n");
  1042.                 }
  1043.                 else
  1044.                   fl = IT_AXE;
  1045.     }
  1046.     else if (self.impulse == 2)
  1047.     {
  1048.         fl = IT_SHOTGUN;
  1049.         if (self.ammo_shells < 1)
  1050.             am = 1;
  1051.     }
  1052.     else if (self.impulse == 3)
  1053.     {
  1054.         fl = IT_SUPER_SHOTGUN;
  1055.         if (self.ammo_shells < 2)
  1056.             am = 1;
  1057.     }               
  1058.     else if (self.impulse == 4)
  1059.     {
  1060.         fl = IT_NAILGUN;
  1061.         if (self.ammo_nails < 1)
  1062.             am = 1;
  1063.     }
  1064.     else if (self.impulse == 5)
  1065.     {
  1066.         fl = IT_SUPER_NAILGUN;
  1067.         if (self.ammo_nails < 2)
  1068.             am = 1;
  1069.     }
  1070.     else if (self.impulse == 6)
  1071.     {
  1072.                 if (self.weapon != IT_GRENADE_LAUNCHER && self.ammo_rockets > 0)
  1073.                 {
  1074.                         fl = IT_GRENADE_LAUNCHER;
  1075.                         if (self.ammo_rockets < 1)
  1076.                         am = 1;
  1077.                 }
  1078.                 else if (self.ammo_shells > 1)
  1079.                 {
  1080.                         fl = IT_FLAMETHROWER;
  1081.                         if (self.ammo_shells < 1)
  1082.             am = 1;
  1083.                 }
  1084.                 else am = 1;
  1085.     }
  1086.     else if (self.impulse == 7)
  1087.     {
  1088.         fl = IT_ROCKET_LAUNCHER;
  1089.         if (self.ammo_rockets < 1)
  1090.             am = 1;
  1091.     }
  1092.     else if (self.impulse == 8)
  1093.     {
  1094.         fl = IT_LIGHTNING;
  1095.         if (self.ammo_cells < 1)
  1096.             am = 1;
  1097.     }
  1098.         else if (self.impulse == 50)
  1099.         {
  1100.                 fl = IT_FLAMETHROWER;
  1101.                 if (self.ammo_rockets < 1)
  1102.                         am = 1;
  1103.         }
  1104.     self.impulse = 0;
  1105.     
  1106.     if (!(self.items & fl))
  1107.     {       // don't have the weapon or the ammo
  1108.         sprint (self, "no weapon.\n");
  1109.         return;
  1110.     }
  1111.     
  1112.     if (am)
  1113.     {       // don't have the ammo
  1114.         sprint (self, "not enough ammo.\n");
  1115.         return;
  1116.     }
  1117.  
  1118. //
  1119. // set weapon, set ammo
  1120. //
  1121.     self.weapon = fl;               
  1122.         if (self.weapon == IT_FLAMETHROWER)
  1123.                 sprint (self, "Flamethrower\n");
  1124.         if (self.weapon == IT_GRENADE_LAUNCHER)
  1125.                 sprint (self, "Grenade Launcher\n");
  1126.  
  1127.         W_SetCurrentAmmo ();
  1128. };
  1129.  
  1130. /*
  1131. ============
  1132. CheatCommand
  1133. ============
  1134. */
  1135. void() CheatCommand =
  1136. {
  1137.         if (deathmatch || coop)
  1138.           return;
  1139.  
  1140.     self.ammo_rockets = 100;
  1141.     self.ammo_nails = 200;
  1142.     self.ammo_shells = 100;
  1143.     self.items = self.items | 
  1144.         IT_AXE |
  1145.                 IT_SHOTGUN |
  1146.         IT_SUPER_SHOTGUN |
  1147.         IT_NAILGUN |
  1148.         IT_SUPER_NAILGUN |
  1149.         IT_GRENADE_LAUNCHER |
  1150.                 IT_FLAMETHROWER |
  1151.                 IT_ROCKET_LAUNCHER |
  1152.         IT_KEY1 | IT_KEY2;
  1153.  
  1154.     self.ammo_cells = 200;
  1155.     self.items = self.items | IT_LIGHTNING;
  1156.  
  1157.     self.weapon = IT_ROCKET_LAUNCHER;
  1158.     self.impulse = 0;
  1159.     W_SetCurrentAmmo ();
  1160. };
  1161.  
  1162. /*
  1163. ============
  1164. CycleWeaponCommand
  1165.  
  1166. Go to the next weapon with ammo
  1167. ============
  1168. */
  1169. void() CycleWeaponCommand =
  1170. {
  1171.     local   float   it, am;
  1172.     
  1173.     it = self.items;
  1174.     self.impulse = 0;
  1175.     
  1176.     while (1)
  1177.     {
  1178.         am = 0;
  1179.  
  1180.         if (self.weapon == IT_LIGHTNING)
  1181.         {
  1182.             self.weapon = IT_AXE;
  1183.         }
  1184.         else if (self.weapon == IT_AXE)
  1185.         {
  1186.                         self.weapon = IT_MORNINGSTAR;
  1187.         }
  1188.                 else if (self.weapon == IT_MORNINGSTAR)
  1189.                 {
  1190.                         self.weapon = IT_SHOTGUN;
  1191.                         if (self.ammo_shells < 1)
  1192.                                 am = 1;
  1193.                 }
  1194.                 else if (self.weapon == IT_SHOTGUN)
  1195.         {
  1196.             self.weapon = IT_SUPER_SHOTGUN;
  1197.             if (self.ammo_shells < 2)
  1198.                 am = 1;
  1199.         }               
  1200.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1201.         {
  1202.             self.weapon = IT_NAILGUN;
  1203.             if (self.ammo_nails < 1)
  1204.                 am = 1;
  1205.         }
  1206.         else if (self.weapon == IT_NAILGUN)
  1207.         {
  1208.             self.weapon = IT_SUPER_NAILGUN;
  1209.             if (self.ammo_nails < 2)
  1210.                 am = 1;
  1211.         }
  1212.         else if (self.weapon == IT_SUPER_NAILGUN)
  1213.         {
  1214.             self.weapon = IT_GRENADE_LAUNCHER;
  1215.             if (self.ammo_rockets < 1)
  1216.                 am = 1;
  1217.         }
  1218.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1219.         {
  1220.                         self.weapon = IT_FLAMETHROWER;
  1221.             if (self.ammo_rockets < 1)
  1222.                 am = 1;
  1223.         }
  1224.                 else if (self.weapon == IT_FLAMETHROWER)
  1225.                 {
  1226.                         self.weapon = IT_ROCKET_LAUNCHER;
  1227.                         if (self.ammo_rockets < 1)
  1228.                                 am = 1;
  1229.                 }
  1230.                 else if (self.weapon == IT_ROCKET_LAUNCHER)
  1231.         {
  1232.             self.weapon = IT_LIGHTNING;
  1233.             if (self.ammo_cells < 1)
  1234.                 am = 1;
  1235.         }
  1236.     
  1237.         if ( (self.items & self.weapon) && am == 0)
  1238.         {
  1239.                         if (self.weapon == IT_FLAMETHROWER)
  1240.                                 sprint(self,"Flamethrower\n");
  1241.                         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1242.                                 sprint(self,"Grenade Launcher\n");
  1243.  
  1244.             W_SetCurrentAmmo ();
  1245.             return;
  1246.         }
  1247.     }
  1248.  
  1249. };
  1250.  
  1251. /*
  1252. ============
  1253. ServerflagsCommand
  1254.  
  1255. Just for development
  1256. ============
  1257. */
  1258. void() ServerflagsCommand =
  1259. {
  1260.     serverflags = serverflags * 2 + 1;
  1261. };
  1262.  
  1263. void() QuadCheat =
  1264. {
  1265.         if (deathmatch || coop)
  1266.           return;
  1267.  
  1268.         self.super_time = 1;
  1269.         self.super_damage_finished = time + 60;
  1270.     self.items = self.items | IT_QUAD;
  1271.     dprint ("quad cheat\n");
  1272. };
  1273.  
  1274. /*
  1275. ============
  1276. ImpulseCommands
  1277.  
  1278. ============
  1279. */
  1280. void() ImpulseCommands =
  1281. {
  1282.     if (self.impulse >= 1 && self.impulse <= 8)
  1283.         W_ChangeWeapon ();
  1284.  
  1285.     if (self.impulse == 9)
  1286.         CheatCommand ();
  1287.     
  1288.     if (self.impulse == 10)
  1289.         CycleWeaponCommand ();
  1290.     if (self.impulse == 11)
  1291.         ServerflagsCommand ();
  1292.  
  1293.         if (self.impulse == 15)
  1294.                 FlareFire ();
  1295.  
  1296.         if (self.impulse == 16)
  1297.                 EntityRemover ();
  1298.  
  1299.         if (self.impulse == 255)
  1300.         QuadCheat ();
  1301.         
  1302.         if (self.impulse == 12)
  1303.                 FlashlightToggle (self);
  1304.  
  1305.         if (self.impulse == 13)
  1306.                 LaserToggle (self);
  1307.  
  1308.         if (self.impulse == 14)
  1309.                 ChasecamToggle ();
  1310.  
  1311.         if (self.impulse == 17)
  1312.                 FootstepsToggle ();
  1313.  
  1314.         if ((self.impulse == 18) || (self.impulse == 19))
  1315.                 ChangeSkin ();
  1316.  
  1317.         if (self.impulse == 187)
  1318.                 BurnSelf ();
  1319.  
  1320.         self.impulse = 0;
  1321. };
  1322.  
  1323. /*
  1324. ============
  1325. W_WeaponFrame
  1326.  
  1327. Called every frame so impulse events can be handled as well as possible
  1328. ============
  1329. */
  1330. void() W_WeaponFrame =
  1331. {
  1332.     if (time < self.attack_finished)
  1333.         return;
  1334.  
  1335.     ImpulseCommands ();
  1336.     
  1337. // check for attack
  1338.     if (self.button0)
  1339.     {
  1340.         SuperDamageSound ();
  1341.         W_Attack ();
  1342.     }
  1343. };
  1344.  
  1345. /*
  1346. ========
  1347. SuperDamageSound
  1348.  
  1349. Plays sound if needed
  1350. ========
  1351. */
  1352. void() SuperDamageSound =
  1353. {
  1354.     if (self.super_damage_finished > time)
  1355.     {
  1356.         if (self.super_sound < time)
  1357.         {
  1358.             self.super_sound = time + 1;
  1359.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1360.         }
  1361.     }
  1362.     return;
  1363. };
  1364.  
  1365. /*
  1366. ======================
  1367. Flashlight Code by Eli
  1368. ======================
  1369. */
  1370.  
  1371. void() FlashlightTrack =
  1372. {
  1373.   local vector src,
  1374.                dir;
  1375.  
  1376.   if (!(self.owner.speed & FLASHLIGHT_ON))
  1377.   {
  1378.     remove(self);
  1379.     return;
  1380.   }
  1381.  
  1382.   makevectors (self.owner.v_angle);
  1383.   src = self.owner.origin + '0 0 16' + v_forward * 10;
  1384.   dir = aim(self.owner, 100000);
  1385.   traceline (src, src + dir * 2048, FALSE, self.owner);
  1386.   if (trace_fraction != 1.0)
  1387.     src = trace_endpos - dir*4;
  1388.   setorigin (self, src);
  1389.   self.nextthink = time + 0.1;
  1390. };
  1391.  
  1392. void(entity FlashlightOwner) FlashlightToggle =
  1393. {
  1394.   local entity Flashlight;
  1395.  
  1396.   if ((self.speed & FLASHLIGHT_ON))
  1397.     self.speed = self.speed - FLASHLIGHT_ON;
  1398.   else
  1399.   {
  1400.     self.speed = self.speed | FLASHLIGHT_ON;
  1401.     Flashlight = spawn();
  1402.     Flashlight.owner = FlashlightOwner;
  1403.     Flashlight.movetype = MOVETYPE_NONE;
  1404.     Flashlight.solid = SOLID_NOT;
  1405.     setmodel (Flashlight, "progs/null.spr");
  1406.     setsize (Flashlight, VEC_ORIGIN, VEC_ORIGIN);
  1407.     setorigin (Flashlight, self.owner.origin);
  1408.     Flashlight.nextthink = time + 0.1;
  1409.     Flashlight.think = FlashlightTrack;
  1410.     Flashlight.effects = EF_DIMLIGHT;
  1411.   }
  1412.  
  1413.   return;
  1414. };
  1415.  
  1416. /*
  1417. End Flashlight Code
  1418. */
  1419.  
  1420. /*
  1421. =============================
  1422. Laser Targeting System by Eli
  1423. =============================
  1424. */
  1425.  
  1426. void () LaserTrack =
  1427. {
  1428.   local vector src,
  1429.                dir;
  1430.  
  1431.   if (!(self.owner.speed & LASER_ON))
  1432.   {
  1433.     remove (self);
  1434.     return;
  1435.   }
  1436.  
  1437.   makevectors (self.owner.v_angle);
  1438.   src = self.owner.origin + '0 0 16' + v_forward * 10;
  1439.   dir = aim(self.owner, 100000);
  1440.   traceline (src, src + dir * 320, FALSE, self.owner);
  1441.   src = 0.1 * src + 0.9 * trace_endpos;
  1442.   setorigin (self, src);
  1443.   self.nextthink = time + 0.1;
  1444. };
  1445.  
  1446. void (entity LaserOwner) LaserToggle =
  1447. {
  1448.   local entity Laser;
  1449.  
  1450.   if ((LaserOwner.speed & LASER_ON))
  1451.   {
  1452.     LaserOwner.speed = LaserOwner.speed - LASER_ON;
  1453.   }
  1454.   else
  1455.   {
  1456.   LaserOwner.speed = LaserOwner.speed | LASER_ON;
  1457.   Laser = spawn ();
  1458.   Laser.owner = LaserOwner;
  1459.   Laser.movetype = MOVETYPE_NONE;
  1460.   Laser.solid = SOLID_NOT;
  1461.   setmodel (Laser, "progs/s_bubble.spr");
  1462.   setsize (Laser, VEC_ORIGIN, VEC_ORIGIN);
  1463.   setorigin (Laser, self.owner.origin);
  1464.   Laser.nextthink = time + 0.1;
  1465.   Laser.think = LaserTrack;
  1466.   }
  1467.  
  1468.   return;
  1469. };
  1470.  
  1471. /*
  1472. End Laser Targeting Code
  1473. */
  1474.  
  1475. /*
  1476. ===============
  1477. ChaseCam by Eli
  1478. ===============
  1479. */
  1480.  
  1481. float ChasecamDistance = 72, ChasecamZ = 16;
  1482.  
  1483. // called either by player or chase cam entities (to restart)
  1484. void (entity ChasecamOwner) ChasecamStart =
  1485. {
  1486.   local entity Chasecam;
  1487.  
  1488.   ChasecamOwner.speed = ChasecamOwner.speed | CHASECAM_ON;
  1489.  
  1490.   Chasecam = spawn ();
  1491.   Chasecam.owner = ChasecamOwner;
  1492.   Chasecam.solid = SOLID_NOT;
  1493.   Chasecam.movetype = MOVETYPE_FLYMISSILE;
  1494.   Chasecam.angles = Chasecam.owner.angles;
  1495.   setmodel (Chasecam, "progs/null.spr");
  1496.   setsize (Chasecam, '0 0 0', '0 0 0');
  1497.   setorigin (Chasecam, Chasecam.owner.origin);
  1498.   Chasecam.classname = "Chasecam";
  1499.   Chasecam.nextthink = time + 0.1; 
  1500.   Chasecam.think = ChasecamTrack;
  1501.   msg_entity = Chasecam.owner; // target of message
  1502.   WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  1503.   WriteEntity (MSG_ONE, Chasecam); // view port
  1504. };
  1505.  
  1506. // secondary think function for cam entities
  1507. void () ChasecamRestart =
  1508. {
  1509.   self.nextthink = time + 0.1;
  1510.  
  1511.   if (self.owner.health <= 0)
  1512.   {
  1513.     remove (self);
  1514.     return;
  1515.   }
  1516.  
  1517.   if (self.owner.waterlevel)
  1518.     return;
  1519.  
  1520.   ChasecamStart (self.owner);
  1521.   remove (self);
  1522. };
  1523.  
  1524. // called only by chase cam entities.
  1525. // opt values:
  1526. // TRUE = remove completely
  1527. // FALSE = remove view but keep alive with ChasecamRestart();
  1528. void (float opt) ChasecamRemove =
  1529. {
  1530.   if ((self.owner.speed & CHASECAM_ON))
  1531.     self.owner.speed = self.owner.speed - CHASECAM_ON;
  1532.  
  1533.   setmodel (self, "progs/null.spr");
  1534.   self.velocity = '0 0 0';
  1535.  
  1536.   msg_entity = self.owner;      // target of message
  1537.   WriteByte (MSG_ONE, SVC_SETVIEWPORT);  
  1538.   WriteEntity (MSG_ONE, self.owner);           // view port
  1539.     
  1540.   if (!opt)
  1541.   {
  1542.     self.nextthink = time + 0.1;
  1543.     self.think = ChasecamRestart;
  1544.   }
  1545.   else
  1546.     remove (self);
  1547. };
  1548.  
  1549. // main think function for cam entities
  1550. // self.ammo_nails = hang-up flag
  1551. void() ChasecamTrack =
  1552. {
  1553.   local vector spot2,
  1554.                dir;
  1555.   local float  dist,
  1556.                cap;
  1557.     
  1558.   self.nextthink = time + 0.1; 
  1559.  
  1560.   if (!(self.owner.speed & CHASECAM_ON))
  1561.   {
  1562.     ChasecamRemove (TRUE);
  1563.     return;
  1564.   }
  1565.  
  1566.   if (self.owner.waterlevel)
  1567.   {
  1568.     ChasecamRemove (FALSE);
  1569.     return;
  1570.   }
  1571.     
  1572.   makevectors (self.owner.v_angle);
  1573.  
  1574.   // Set initial spot before clipping, compensating for looking up
  1575.   // and down so the player doesn't block the view
  1576.   spot2 = self.owner.origin - (v_forward * self.ammo_shells);
  1577.   spot2_z = spot2_z + ChasecamZ;
  1578.   if (self.owner.v_angle_x < 0)
  1579.     spot2 = spot2 - self.owner.v_angle_x * 0.6 * v_up;
  1580.   if (self.owner.v_angle_x > 0)
  1581.     spot2 = spot2 + self.owner.v_angle_x * 0.6 * v_up;
  1582.  
  1583.   traceline (self.owner.origin, spot2, TRUE, self.owner);
  1584.   self.ammo_shells = vlen (trace_endpos - self.owner.origin);
  1585.   spot2 = trace_endpos + (v_forward * 2);
  1586.  
  1587.   traceline (spot2, spot2 + '0 0 32', TRUE, self.owner );
  1588.   if (trace_fraction < 1 )
  1589.     spot2 = trace_endpos - '0 0 32';
  1590.  
  1591.   dir = normalize (spot2 - self.origin);
  1592.   dist = vlen (spot2 - self.origin);
  1593.  
  1594.   traceline (self.origin, spot2, TRUE, self.owner);
  1595.   if (trace_fraction == 1)
  1596.   {
  1597.     self.angles = self.owner.angles;
  1598.     cap = dist * 0.2;
  1599.  
  1600.     if (cap > 5.2)
  1601.       self.velocity = dir * dist * 5.2;
  1602.     else if (cap > 1)
  1603.       self.velocity = dir * dist * cap;
  1604.     else
  1605.       self.velocity = dir * dist;
  1606.  
  1607.     if ((vlen(self.owner.origin - self.origin)) < 30)
  1608.     {
  1609.       self.velocity = self.velocity * 2;
  1610.     }
  1611.   }
  1612.   else
  1613.     setorigin (self, spot2);
  1614.    
  1615.   self.ammo_shells = self.ammo_shells + 4;
  1616.  
  1617.   if (self.ammo_shells > ChasecamDistance)
  1618.     self.ammo_shells = ChasecamDistance;
  1619.  
  1620.   // respawn if missile ent. get's hung up
  1621.   if (self.oldorigin == self.origin)
  1622.   {
  1623.     if (dist > 30)
  1624.       self.ammo_nails = self.ammo_nails + 1;
  1625.   }
  1626.  
  1627.   if (self.ammo_nails > 3)
  1628.   {
  1629.     ChasecamStart (self.owner);
  1630.     remove (self);
  1631.     return;
  1632.   }
  1633.  
  1634.   self.oldorigin = self.origin;
  1635. };
  1636.  
  1637. void () ChasecamToggle =
  1638. {
  1639.   if ((self.speed & CHASECAM_ON))
  1640.   {
  1641.     cvar_set ("scr_ofsx", "-2");
  1642.     cvar_set ("scr_ofsy", "2");
  1643.     cvar_set ("r_drawviewmodel", "1");
  1644.     self.speed = self.speed - CHASECAM_ON;
  1645.   }
  1646.   else
  1647.   {
  1648.     cvar_set ("scr_ofsx", "0");
  1649.     cvar_set ("scr_ofsy", "0");
  1650.     cvar_set ("r_drawviewmodel", "0");
  1651.     ChasecamStart (self);
  1652.   }
  1653. };
  1654.  
  1655. /*
  1656. End Chasecam Code
  1657. */
  1658.  
  1659. /*
  1660. =====================
  1661. Entity Remover by Eli
  1662. =====================
  1663. */
  1664.  
  1665. void () EntityRemover =
  1666. {
  1667.   local vector src, dir;
  1668.     
  1669.   sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  1670.  
  1671.   makevectors (self.v_angle);
  1672.   self.attack_finished = time + 0.5;
  1673.   dir = aim (self, 100000);
  1674.   src = self.origin + '0 0 16' + v_forward * 10;
  1675.   traceline (src, src + dir * 2048, FALSE, self);
  1676.   if (trace_ent != world)
  1677.     remove (trace_ent);
  1678. };
  1679.  
  1680. /*
  1681. End Entity Remover Code
  1682. */
  1683.  
  1684. /*
  1685. ================
  1686. Flare Gun by Eli
  1687. ================
  1688. */
  1689.  
  1690. void () FlareFire =
  1691. {
  1692.   local entity Flare;
  1693.  
  1694.   makevectors (self.v_angle);
  1695.  
  1696.   sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  1697.   self.attack_finished = time + 0.5;
  1698.   self.punchangle_x = -2;
  1699.  
  1700.   Flare = spawn ();
  1701.   Flare.owner = self;
  1702.   Flare.movetype = MOVETYPE_FLYMISSILE;
  1703.   Flare.solid = SOLID_BBOX;
  1704.   Flare.velocity = aim (self, 1000);
  1705.   Flare.velocity = Flare.velocity * 1000;
  1706.   Flare.angles = vectoangles (Flare.velocity);
  1707.   Flare.touch = FlareTouch;
  1708.   Flare.classname = "Flare";
  1709.   Flare.think = SUB_Remove;
  1710.   Flare.nextthink = time + 7;
  1711.   setmodel (Flare, "progs/laser.mdl");
  1712.   setsize (Flare, VEC_ORIGIN, VEC_ORIGIN);               
  1713.   setorigin (Flare, self.origin + '0 0 16');
  1714.   Flare.effects = EF_DIMLIGHT;
  1715. };
  1716.  
  1717. void () FlareTouch =
  1718. {
  1719.   local float rand;
  1720.  
  1721.   if (other == self.owner)
  1722.     return;
  1723.  
  1724.   if (other.classname == "door" || other.classname == "plat")
  1725.   {
  1726.     remove (self);
  1727.     return;
  1728.   }
  1729.  
  1730.   if (other.solid == SOLID_TRIGGER)
  1731.     return;
  1732.  
  1733.   if (other.takedamage)
  1734.   {
  1735.     spawn_touchblood (2);
  1736.     T_Damage (other, self, self.owner, 1);
  1737.     remove (self);
  1738.     return;
  1739.   }
  1740.  
  1741.   self.movetype = MOVETYPE_NONE;
  1742.   self.solid = SOLID_NOT;
  1743.   self.origin = self.origin - self.velocity * 0.005;
  1744.   self.velocity = '0 0 0';
  1745.   self.touch = SUB_Null;
  1746. };
  1747.  
  1748. /*
  1749. End Flare Gun Code
  1750. */
  1751.  
  1752. /*
  1753. Footsteps Code
  1754. */
  1755.  
  1756. void () FootstepsToggle =
  1757. {
  1758.   if ((self.speed & FOOTSTEPS_ON))
  1759.     self.speed = self.speed - FOOTSTEPS_ON;
  1760.   else
  1761.     self.speed = self.speed | FOOTSTEPS_ON;
  1762. };
  1763.  
  1764. // End Footsteps Code
  1765.  
  1766. /*
  1767. ========================
  1768. Eject shells code by Eli
  1769. ========================
  1770. */
  1771.  
  1772. void (vector src, vector dir, float punch, vector spread) ShellEject =
  1773. {
  1774.   local float flip;
  1775.   local vector transform;
  1776.   local entity shell;
  1777.  
  1778.   shell = spawn ();
  1779.   shell.owner = self;
  1780.   shell.movetype = MOVETYPE_BOUNCE;
  1781.   shell.solid = SOLID_BBOX;
  1782.   shell.angles = vectoangles (dir);
  1783.   shell.think = SUB_Remove;
  1784.   shell.nextthink = time + 5;
  1785.   setmodel (shell, "progs/shelcase.mdl");
  1786.   setsize (shell, VEC_ORIGIN, VEC_ORIGIN);
  1787.   setorigin (shell, src);
  1788.  
  1789.   flip = crandom ();
  1790.   spread_x = spread_x * flip;
  1791.   flip = crandom ();
  1792.   spread_y = spread_y * flip;
  1793.   flip = crandom ();
  1794.   spread_z = spread_z * flip;
  1795.  
  1796.   transform_x = dir_y + spread_x;
  1797.   transform_y = 0 - dir_x + spread_y;
  1798.   transform_z = dir_z + spread_z;
  1799.   shell.velocity = transform * punch;
  1800.  
  1801.   flip = random ();
  1802.   if (flip < 0.25)
  1803.     shell.avelocity = '300 300 300';
  1804.   else if (flip < 0.5)
  1805.       shell.avelocity = '150 300 100';
  1806.   else if (flip < 0.75)
  1807.       shell.avelocity = '200 100 0';
  1808.   else
  1809.     shell.avelocity = '400 200 100';
  1810. };
  1811.  
  1812. /*
  1813. End Shell Eject Code
  1814. */
  1815.  
  1816. /*
  1817. ====================
  1818. Multiskin Code Start
  1819. ====================
  1820. */
  1821.  
  1822. void () ChangeSkin =
  1823. {
  1824.   if (self.impulse == 18)
  1825.     self.skin = self.skin + 1;
  1826.  
  1827.   if (self.impulse == 19)
  1828.     self.skin = self.skin - 1;
  1829.  
  1830.   dprint ("Skin Changed");
  1831. };
  1832.  
  1833. /*
  1834. End Multiskin Code
  1835. */
  1836.